//
//  NetworkTools.swift
//  sinaWeiBo
//
//  Created by weixq on 15/8/1.
//  Copyright © 2015年 weixq. All rights reserved.
//

import UIKit
import AFNetworking

// 错误的类别标记
private let HMErrorDomainName = "com.ittheima.error.network"

private enum HMNetworkError: Int {
    case emptyDataError = -1
    case emptyTokenError = -2
    
    private var errorDescrption: String {
        switch self {
        case .emptyDataError : return "空数据"
        case .emptyTokenError : return "Token 为空"
        }
    }
    
    private func error() -> NSError {
        return NSError(domain: HMErrorDomainName, code: rawValue, userInfo: [HMErrorDomainName: errorDescrption])
    }
}

private enum HMNetworkMethod: String {
    case GET = "GET"
    case POST = "POST"
}

class NetworkTools: AFHTTPSessionManager {
    
    // MARK: - 网络回调
    typealias HMNetFinishedCallBack = (result: [String: AnyObject]?, error: NSError?)->()
    
    // MARK: - 应用程序相关
    private let clientId = "3039243534"
    private let appSecret = "74d17afab1734910f388024eb3d1433b"
    let redirectUrl = "http://www.baidu.com"
    
    // 单例
    static let sharedTools:NetworkTools = {
        let baseURL = NSURL(string: "https://api.weibo.com/")!
        let tools = NetworkTools(baseURL: baseURL)
        tools.responseSerializer.acceptableContentTypes = NSSet(objects: "application/json", "text/json", "text/javascript", "text/plain") as Set<NSObject>
        return tools
    }()
    
    // MARK: - 检查生成Token
    private func tokenDict(finished: HMNetFinishedCallBack) -> [String:AnyObject]? {
        if UserAccount.loadAccount()?.access_token == nil{
            let error = HMNetworkError.emptyTokenError.error()
            finished(result: nil, error: error)
            return nil
        }
        
        print("access_token ------ \(UserAccount.loadAccount()!.access_token!)")
        return ["access_token": UserAccount.loadAccount()!.access_token!]
    }
    
    
    // MARK: - 加载用户信息
    func loadUserInfo(uid: String, finished:HMNetFinishedCallBack){
        
        // 判断 token 是否存在
        guard var params = tokenDict(finished) else {
            return
        }
        
        
        let urlString = "2/users/show.json"
        params["uid"] = uid
  
        request(HMNetworkMethod.GET, urlString: urlString, params: params, finished: finished)
    
    }
    
    
    // MARK: - 发布微博
    // status 微博文字
    // image  微博图片
    // finished  完成回调
    func sendStatus(status: String, image: UIImage?, finished: HMNetFinishedCallBack) {
        guard var params = tokenDict(finished) else {
            return
        }
        
        params["status"] = status
        
        // post 发布微博
        if image == nil {
            request(HMNetworkMethod.POST, urlString: "2/statuses/update.json", params: params, finished: finished)
        }else{
            uploadImage("https://upload.api.weibo.com/2/statuses/upload.json", image: image!, params: params, finished: finished)
        }
    }
    
    // MARK: - 加载微博数据
    // since_id 返回Id比since_id大的微博（既比since_id时间晚的微博），默认为0
    ///max_id   返回ID小于或者等于max_id的微博，默认为0
    func loadstatus(since_id: Int, max_id: Int, finished: HMNetFinishedCallBack) {
        guard var params = tokenDict(finished) else {
            return
        }
        
        if since_id > 0 {
            params["since_id"] = since_id
        }
        
        if max_id > 0 {
        
            params["max_id"] = max_id - 1
        }
        
        let urlString = "2/statuses/home_timeline.json"
        request(HMNetworkMethod.GET, urlString: urlString, params: params, finished: finished)
    }
    
    /// 返回授权地址
    func authUrl() -> NSURL {
        let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(clientId)&redirect_uri=\(redirectUrl)"
        return NSURL(string: urlString)!
    }
    
    func loadAccessToken(code: String, finished: HMNetFinishedCallBack){
        let urlString = "https://api.weibo.com/oauth2/access_token"
        let params = ["client_id" : clientId,
            "client_secret" : appSecret,
            "grant_type" : "authorization_code",
            "code" : code,
            "redirect_uri" : redirectUrl]
        
        request(HMNetworkMethod.POST, urlString: urlString, params: params, finished: finished)
 
    }

    private func request(method: HMNetworkMethod, urlString: String, params: [String: AnyObject], finished:HMNetFinishedCallBack){
    
        // 1. 定义成功的包
        let successCallBack: (NSURLSessionDataTask!, AnyObject!) -> Void = { (_, JSON) -> Void in
            
            if let result = JSON as? [String: AnyObject] {
                // 有结果的回调
                finished(result: result, error: nil)
            } else {
                // 没有错误，同时没有结果
                print("没有数据 \(method) Request \(urlString)")
                
                finished(result: nil, error: HMNetworkError.emptyDataError.error())
            }
        }
        
        // 2. 定义失败的闭包
        let failedCallBack: (NSURLSessionDataTask!, NSError!) -> Void = { (_, error) -> Void in
            print(error)
            
            finished(result: nil, error: error)
        }
        
        // 3. 根据 method 来选择执行的方法
        switch method {
        case .GET:
            GET(urlString, parameters: params, success: successCallBack, failure: failedCallBack)
        case .POST:
            POST(urlString, parameters: params, success: successCallBack, failure: failedCallBack)
        }
    }
    
    private func uploadImage(urlString: String, image: UIImage, params: [String: AnyObject], finished:HMNetFinishedCallBack) {
        
        // 1. 定义成功的包
        let successCallBack: (NSURLSessionDataTask!, AnyObject!) -> Void = { (_, JSON) -> Void in
            
            if let result = JSON as? [String: AnyObject] {
                // 有结果的回调
                finished(result: result, error: nil)
            } else {
                // 没有错误，同时没有结果
                print("没有数据\(urlString)")
                
                finished(result: nil, error: HMNetworkError.emptyDataError.error())
            }
        }
        
        // 2. 定义失败的闭包
        let failedCallBack: (NSURLSessionDataTask!, NSError!) -> Void = { (_, error) -> Void in
            print(error)
            
            finished(result: nil, error: error)
        }
        
        POST(urlString, parameters: params, constructingBodyWithBlock: { (formData) -> Void in
            
            // 1. 将 image 转化成二进制数据
            let data = UIImagePNGRepresentation(image)
            
            // 2. 构造数据体
            /**
                name: 服务器请求的字段
                fileName： 保存在服务器的文件名，提示：如果结构文档没有指定文件名参数，可以随便写
                mimeType： 告诉服务器上传文件的类型，如果不想告诉服务器，可以使用 application/octet-stream
                    格式：大类/小类
                    常见格式：
                        image/png
                        image/jpg
                        image/gig
                        text/html
                        text/plain
            */
            
            formData.appendPartWithFileData(data, name: "pic", fileName: "suiyi", mimeType: "application/octet-stream")
            }, success: successCallBack, failure: failedCallBack)
    }
    
}
